package com.jy.adscm.core.aspect;

import com.jy.adscm.annotation.AdscmLogger;
import com.jy.adscm.bean.AdscmLogEntity;
import com.jy.adscm.core.dao.mysql.AdscmLogMapper;
import com.jy.adscm.security.utils.Token;
import com.jy.adscm.utils.AdscmBaseUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @author yyy
 * @ClassName AdscmOperateAspect
 * @Description 系统日志切入类
 * @date 2018/8/6 17:29
 */
@Component
@Aspect
public class AdscmOperateAspect {

    @Autowired
    RedisTemplate<Object,Token> tokenRedisTemplate;
    @Autowired
    AdscmLogMapper adscmLogMapper;

    Logger logger = LoggerFactory.getLogger(getClass());

    @Pointcut("@annotation(com.jy.adscm.annotation.AdscmLogger)")
    private void cut() { }


    /**
     * 正常返回通知
     * @param joinPoint
     */
    @AfterReturning(pointcut = "cut() && @annotation(adscmLogger)")
    public void doAfter(JoinPoint joinPoint,AdscmLogger adscmLogger) {

        try{

            logger.info("正常返回通知...");

            AdscmLogEntity logEntity =  loadAdscmLogEntity(joinPoint,adscmLogger);
            logEntity.setResult("成功");

            adscmLogMapper.insert(logEntity);


        }catch (Exception e){
            logger.error("正常返回通知日志异常",e);
        }

    }

    /**
     * 异常通知
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "cut() && @annotation(adscmLogger)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable e, AdscmLogger adscmLogger){
        try{

            logger.info("异常通知...");
            AdscmLogEntity logEntity =  loadAdscmLogEntity(joinPoint,adscmLogger);
            logEntity.setResult("失败");
            logEntity.setError(e.getMessage());
            adscmLogMapper.insert(logEntity);


        }catch (Exception e1){
            logger.error("异常返回通知日志异常",e1);
        }
    }

    private AdscmLogEntity loadAdscmLogEntity(JoinPoint joinPoint, AdscmLogger adscmLogger){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();
        String tokenId = request.getParameter("tokenId");

        Token token = AdscmBaseUtils.getInstance().getTokenByTokenId(tokenId,tokenRedisTemplate);

        String ip = AdscmBaseUtils.getInstance().getIPAddress(request);
        String operation = adscmLogger.value();
        String modular = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName();
        String operParam = "";
        Object[] args = joinPoint.getArgs();
        if (args != null && args.length>0){
            for (Object obj :
                    args) {
                operParam += " ; " + obj;
            }
            operParam = operParam.substring(operParam.indexOf(" ; ") + 2);
        }

        AdscmLogEntity logEntity = new AdscmLogEntity();
        logEntity.setName(token.getUser().getName());
        logEntity.setUserId(token.getUser().getId());
        logEntity.setUsername(token.getUser().getUsername());
        logEntity.setReqIp(ip);
        logEntity.setOperation(operation);
        logEntity.setOperParam(operParam);
        logEntity.setReqTime(new Date());
        logEntity.setReqModular(modular);

        return logEntity;
    }


}
